package pl.edu.agh.winmon.widget;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.event.ChartChangeEvent;
import org.jfree.chart.event.ChartChangeEventType;
import org.jfree.chart.event.ChartChangeListener;
import org.jfree.data.time.DateRange;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.experimental.chart.swt.ChartComposite;

import pl.edu.agh.winmon.analise.AverageCpuSeriesProvider;
import pl.edu.agh.winmon.analise.CoreLoadSeriesProvider;
import pl.edu.agh.winmon.analise.SessionSeriesProvider;
import pl.edu.agh.winmon.hibernate.CpuInfo;
import pl.edu.agh.winmon.hibernate.Session;

/**
 * This is page which provides information about CPU (static information).
 * 
 * @author kret
 */
public class CPUInfoWidget extends SessionUpdatableComposite {

	/**
	 * Constructor.
	 * 
	 * @param parent
	 *            widget's parent
	 */
	public CPUInfoWidget(Composite parent) {
		super(parent, SWT.NONE);
		setLayout(new FillLayout(SWT.VERTICAL));
		createControls();
	}

	private Label cpuVendor;

	private Label cache;

	private Label cpuSpeed;

	private Label cpuModel;

	private Label cpuCores;

	private Group chartGroup;

	private TimePickerWidget timePicker;

	private ChartComposite chartComposite;

	private static SessionSeriesProvider averageLoadSeriesProvider = new AverageCpuSeriesProvider();

	private static SessionSeriesProvider coreLoadSeriesProvider = new CoreLoadSeriesProvider();

	private Session currentSession;

	private String AVERAGE_LABEL = "Total CPU usage in time";

	private String CORE_LABEL = "Cores usage in time";

	private Combo chartCombo;

	private SelectionListener repaintListener = new SelectionAdapter() {
		@Override
		public void widgetSelected(SelectionEvent arg0) {
			repaintChart();
		}
	};

	private void repaintChart() {

		TimeSeriesCollection xyDataset = ((SessionSeriesProvider) chartCombo
				.getData(chartCombo.getText())).provideSeries(currentSession,
				timePicker.getStartDate(), timePicker.getEndDate());

		JFreeChart chart = ChartFactory.createTimeSeriesChart(
				"Average CPU load", // Title
				"Time", // X-Axis label
				"CPU load", // Y-Axis label
				xyDataset, // Dataset
				false, // Show legend
				false, // Show tooltip
				false);

		if (chartComposite == null) {
			chartComposite = new ChartComposite(chartGroup, SWT.BORDER, chart);
			GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
			gridData.horizontalSpan = 3;

			chartComposite.setLayoutData(gridData);
			chartGroup.layout();
		} else {
			chartComposite.setChart(chart);
			chartComposite.redraw();
			chartGroup.layout();
		}

		chartComposite.getChart().addChangeListener(new ChartChangeListener() {

			@Override
			public void chartChanged(ChartChangeEvent arg0) {
				if (arg0.getChart() != null)
					if (arg0.getType().equals(ChartChangeEventType.GENERAL)) {
						timePicker.getStartTimeCombo().setDate(
								((DateRange) arg0.getChart().getXYPlot()
										.getDomainAxis().getRange())
										.getLowerDate());
						timePicker.getEndTimeCombo().setDate(
								((DateRange) arg0.getChart().getXYPlot()
										.getDomainAxis().getRange())
										.getUpperDate());
					}
			}
		});
	}

	/**
	 * helper methods which allows to create all graphic controls.
	 */
	public void createControls() {

		Group group = new Group(this, SWT.NONE);
		group.setText("CPU info");
		group.setLayout(new GridLayout(2, true));

		// CpuInfo c session.getCpuInfo();

		Label label = new Label(group, SWT.NONE);
		label.setText("Cpu vendor");
		cpuVendor = new Label(group, SWT.NONE);
		cpuVendor.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		label = new Label(group, SWT.NONE);
		label.setText("Cpu model");
		cpuModel = new Label(group, SWT.NONE);
		cpuModel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		label = new Label(group, SWT.NONE);
		label.setText("Cpu speed");
		cpuSpeed = new Label(group, SWT.NONE);
		cpuSpeed.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		label = new Label(group, SWT.NONE);
		label.setText("Cpu cores");
		cpuCores = new Label(group, SWT.NONE);
		cpuCores.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		label = new Label(group, SWT.NONE);
		label.setText("Cpu cache");
		cache = new Label(group, SWT.NONE);
		cache.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		chartGroup = new Group(this, SWT.NONE);
		chartGroup.setLayout(new GridLayout(3, false));
		chartGroup.setText("CPU charts");

		timePicker = new TimePickerWidget(chartGroup);

		timePicker.addSelectionListener(repaintListener);
		Label screenshotDate = new Label(chartGroup, SWT.NONE);
		screenshotDate.setText("Choose chart");

		chartCombo = new Combo(chartGroup, SWT.NONE);
		chartCombo.add(AVERAGE_LABEL);
		chartCombo.setData(AVERAGE_LABEL, averageLoadSeriesProvider);
		chartCombo.add(CORE_LABEL);
		chartCombo.setData(CORE_LABEL, coreLoadSeriesProvider);
		chartCombo.select(0);
		chartCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		chartCombo.addSelectionListener(repaintListener);
	}

	public void updateOnSessionChange(Session session) {
		CpuInfo cpuInfo = session.getCpuInfo();
		cpuVendor.setText(cpuInfo.getCpuVendor());
		cpuModel.setText(cpuInfo.getCpuModel());
		cpuSpeed.setText(cpuInfo.getCpuSpeed().toString());
		cpuCores.setText(cpuInfo.getCpuCores().toString());
		cache.setText(cpuInfo.getCache().toString());
		timePicker.setSession(session);
		currentSession = session;
		repaintChart();
	}

}
